package com.cjb.cloudsystem.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.cjb.cloudsystem.cache.SysParamsCache;
import com.cjb.cloudsystem.entity.SysParams;
import com.cjb.cloudsystem.enums.SysParamsEnum;
import com.cjb.cloudsystem.mapper.SysParamsMapper;
import com.cjb.cloudsystem.service.SysParamsService;
import com.cjb.cloudsystem.vo.SysCaptchaVO;
import com.cjb.cloudsystem.vo.SysParamsVO;
import com.cjb.common.common.cache.RedisCache;
import com.cjb.common.common.cache.RedisKeys;
import com.cjb.common.exception.ServerException;
import com.cjb.common.mybatisUtil.impl.BaseRepositoryImpl;
import com.cjb.common.util.Common;
import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

import static com.cjb.cloudsystem.enums.SysParamsEnum.CAPTCHA_EXPIRE;

/**
 * @Author chenjinbin
 * @Package IntelliJ IDEA
 * @Class SysParamssServiceImpl
 * @Date 2023-07-27 21:41
 */
@Service
@AllArgsConstructor
@Slf4j
public class SysParamsRepositoryImpl extends BaseRepositoryImpl<SysParamsMapper, SysParams> implements SysParamsService {
    /**
     * 注入缓存仓库
     */
    private final RedisCache redisCache;

    /*
     * 注入mapper层
     */
    private final SysParamsMapper sysParamsMapper;
    /**
     * 参数管理 KEY
     */
    private final String SYSTEM_PARAMS_KEY = "system:params";
    /**
     * 注入控制值的仓库
     */
    private final SysParamsCache sysParamsCache;

    /**
     * 单体保存
     *
     * @return
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public boolean save(SysParams sysParams) {
        log.info("first params {}",sysParams.getParamKey());
        log.info("second params {}",redisCache.hGet(SYSTEM_PARAMS_KEY,sysParams.getParamKey()));
        if (Common.isNotNull(sysParams.getParamKey()) && Common.isNotNull(redisCache.hGet(SYSTEM_PARAMS_KEY,sysParams.getParamKey()))){
            log.info("设置缓存");
            log.info("打印被设置的 {}",sysParams.getParamValue());
            redisCache.hSet(SYSTEM_PARAMS_KEY, sysParams.getParamKey(), sysParams.getParamValue());
        }

        if (Common.isNull(sysParams.getId())){
            sysParams.setDeleted(0);
        }
        if (sysParams.getId() == null) {
            // 新增操作
            baseMapper.insert(sysParams);
        } else {
            // 修改操作
            baseMapper.updateById(sysParams);
        }
        return true;
    }

    /**
     * 批量保存
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public Integer listSave(List<SysParams> sysParams) {
        return sysParamsMapper.insertBatchSomeColumn(sysParams);
    }

    /**
     * 批量更新
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public void listUpdate(List<SysParams> sysParams) {
//        sysParamsMapper.saveOrUpdateBatch(sysParams);
        sysParamsMapper.insertBatchSomeColumn(sysParams);
    }

    /**
     * 批量删除
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public void listDelete(List<SysParams> sysParams) {
        List<Long> collect = sysParams.stream().map(SysParams::getId).distinct().collect(Collectors.toList());
        sysParamsMapper.deleteBatchIds(collect);
    }

    /**
     * 通过id删除
     *
     * @return
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public int deleteById(SysParams sysParams) {
        return sysParamsMapper.deleteById(sysParams.getId());
    }

    /**
     * 单个查询
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public SysParams queryById(Long id) {
        return sysParamsMapper.selectById(id);
    }

    @Override
    public Page queryPage(Page sysParamsPage, SysParamsVO sysParams) {
        return sysParamsMapper.selectPage(sysParamsPage, getWrapper(sysParams));
    }

    /**
     * 条件查询
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    public List<SysParams> queryBySysParams(SysParamsVO sysParams){
         return sysParamsMapper.selectList(getWrapper(sysParams));
    }

    /**
     * 查询属性
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    private LambdaQueryWrapper<SysParams> getWrapper(SysParamsVO query) {
        LambdaQueryWrapper<SysParams> wrapper = Wrappers.lambdaQuery();
        if (Common.isNotNull(query.getId())) {
            wrapper.eq(SysParams::getId, query.getId());
        }
        if (Common.isNotNull(query.getId())) {
            wrapper.eq(SysParams::getParamName, query.getParamName());
        }
        if (Common.isNotNull(query.getId())) {
            wrapper.eq(SysParams::getParamType, query.getParamType());
        }
        if (Common.isNotNull(query.getId())) {
            wrapper.eq(SysParams::getParamKey, query.getParamKey());
        }
        if (Common.isNotNull(query.getId())) {
            wrapper.eq(SysParams::getParamValue, query.getParamValue());
        }
        if (Common.isNotNull(query.getId())) {
            wrapper.eq(SysParams::getRemark, query.getRemark());
        }
        if (Common.isNotNull(query.getId())) {
            wrapper.eq(SysParams::getTenantId, query.getTenantId());
        }
        if (Common.isNotNull(query.getId())) {
            wrapper.eq(SysParams::getVersion, query.getVersion());
        }
        if (Common.isNotNull(query.getId())) {
            wrapper.eq(SysParams::getDeleted, query.getDeleted());
        }
        if (Common.isNotNull(query.getId())) {
            wrapper.eq(SysParams::getCreator, query.getCreator());
        }
        if (Common.isNotNull(query.getId())) {
            wrapper.eq(SysParams::getCreateTime, query.getCreateTime());
        }
        if (Common.isNotNull(query.getId())) {
            wrapper.eq(SysParams::getUpdater, query.getUpdater());
        }
        if (Common.isNotNull(query.getId())) {
            wrapper.eq(SysParams::getUpdateTime, query.getUpdateTime());
        }
        wrapper.orderByDesc(SysParams::getId);
        return wrapper;
    }

    /**
     * 返回全部信息
     *
     * @Author chenjinbin
     * @Value
     * @Title
     */
    @Override
    public List<SysParams> returnAllData() {
        return sysParamsMapper.selectList(null);
    }

    @Override
    public boolean isCaptchaEnabled() {
        String aBoolean = getBoolean(SysParamsEnum.LOGIN_CAPTCHA.name());
        //log.info("验证码结果{}", aBoolean);
        return Boolean.parseBoolean(aBoolean);
    }

    /**
     * 生成验证码 generate
     *
     * @param
     * @return
     * @author chenjinbin
     * @email 2213859123@qq.com
     * @date 2023-07-12 9:10
     */
    @Override
    public SysCaptchaVO generate() {
        //生成key
        String key = UUID.randomUUID().toString();

        //生成验证码
        SpecCaptcha captcha = new SpecCaptcha(150, 40);
        captcha.setLen(5);
        captcha.setCharType(Captcha.TYPE_DEFAULT);
        String image = captcha.toBase64();


        // 保存到缓存 -- 处理策略
        String param = sysParamsCache.get(CAPTCHA_EXPIRE.name());
        String redisKey = RedisKeys.getCaptchaKey(key);
        if (StrUtil.isNotBlank(param)) {
            log.info("缓存中过期时间为{}", param);
            redisCache.set(redisKey, captcha.text(), Integer.parseInt(param));
        } else {
            log.info("默认过期时间1000");
            redisCache.set(redisKey, captcha.text(), 1000);
        }
        // 返回数据 -- 可序列化
        SysCaptchaVO sysCaptchaVO = new SysCaptchaVO();
        sysCaptchaVO.setKey(key);
        sysCaptchaVO.setImage(image);

        return sysCaptchaVO;
    }

    /**
     * 验证码校验
     *
     * @param
     * @return
     * @author chenjinbin
     * @email 2213859123@qq.com
     * @date 2023-07-12 9:10
     */
    @Override
    public boolean validateCaptcha(String key, String code) {
        // 如果关闭了验证码，则直接效验通过
        if (!isCaptchaEnabled()) {
            return true;
        }

        //进入校验
        //空值校验
        if (StrUtil.isBlank(key) || StrUtil.isBlank(code)) {
            return false;
        }
        String captcha = getCaptchaKey(key);
        log.info("打印生成的验证码结果 {}",captcha);
        return code.equalsIgnoreCase(captcha);
    }

    //拿到验证码 -- 删除验证码
    private String getCaptchaKey(String key) {
        String captchaKey = RedisKeys.getCaptchaKey(key);
        log.info("得到传入key:{}", captchaKey);
        String captcha = (String) redisCache.get(captchaKey);
        log.info("得到key{}", captcha);
        //删除验证过的
        if (StrUtil.isNotBlank(captcha)) {
            redisCache.delete(key);
        }
        return captcha;
    }


    private String getBoolean(String paramKey) {
        String value = sysParamsCache.get(paramKey);
        if (StrUtil.isNotBlank(value)) {
            return value;
        }

        // 如果缓存没有，则查询数据库
        SysParams entity = baseMapper.selectOne(new QueryWrapper<SysParams>().eq("param_key", paramKey));
        //log.info("查询结果{}", JsonUtils.toJsonString(entity));
        if (entity == null) {
            throw new ServerException("参数值不存在，paramKey：" + paramKey);
        }

        //保存到缓存
        sysParamsCache.save(entity.getParamKey(), entity.getParamValue());

        return entity.getParamValue();
    }


}